package com.iflytek.iot.platform.tracing.config;

import com.iflytek.drip.log.loglib.HostUnreachableExcept;
import com.iflytek.drip.log.loglib.clients.AbstractSendLog;
import com.iflytek.drip.log.loglib.config.HostInfo;
import com.iflytek.drip.log.loglib.config.LogLibConfig;
import com.iflytek.drip.log.loglib.local.FileHelper;
import com.iflytek.drip.log.loglib.local.FileHelperManager;
import com.iflytek.drip.log.loglib.router.RouterConfig;
import com.iflytek.drip.log.loglib.router.RouterUtils;
import com.iflytek.drip.log.loglib.sender.Sender;
import com.iflytek.drip.log.loglib.sender.SenderHelper;
import com.iflytek.drip.log.loglib.serialhelper.DealerType;
import com.iflytek.drip.log.loglib.serialhelper.Router;
import com.iflytek.drip.log.loglib.utils.EventDeliveryException;
import com.iflytek.drip.log.loglib.utils.EventHelper;
import com.iflytek.drip.log.loglib.utils.LogValidator;
import com.iflytek.iot.common.utils.RandomUtils;
import com.thoughtworks.xstream.XStream;
import org.apache.commons.lang.StringUtils;
import org.apache.flume.thrift.ThriftFlumeEvent;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.ByteBuffer;
import java.util.*;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class TraceLogClient extends AbstractSendLog {
    private static final String className = TraceLogClient.class.getName();
    private Sender sender = null;
    private final Lock stateLock = new ReentrantLock(true);
    private String configFile = null;
    private TraceLogClient.State connState;
    private FileHelper logfile = null;
    private String[] mustContainKeys = null;
    private RouterUtils router;


    public TraceLogClient() {
        this.connState = TraceLogClient.State.INIT;
    }

    public String getConfigFile() {
        return this.configFile;
    }

    public void configure(String configFile, LogLibConfig config) throws IOException, HostUnreachableExcept {
        this.stateLock.lock();

        try {
            this.configFile = configFile;
            this.config = config;
            this.mustContainKeys = config.getMasterContainKeys().split(",");
            this.sender = SenderHelper.getSender(this, configFile, config);
            this.sender.configure();
            this.logfile = FileHelperManager.getLogInstance(this.configFile, config);
            this.connState = TraceLogClient.State.READY;
            if (config.isOpenFilter() && !StringUtils.isEmpty(config.getFilterFile())) {
                this.initRouter(config.getFilterFile());
            }

            this.logfile.writeLog("load TraceLogClient success. " + config.toString(), className, "info");
            if (config.isStartCheck()) {
                this.sender.pingCheck();
            }
        } finally {
            this.stateLock.unlock();
        }

    }

    public int getSendQueueCurrentSize() {
        return this.sender.getQueueSize();
    }

    private void checkActive() throws EventDeliveryException {
        if (!this.isActive()) {
            this.logfile.writeLog(((HostInfo)this.config.getHostInfo().get(RandomUtils.randomInt(0, this.config.getHostInfo().size()))).toString() + " " + "Client was closed. " + "Please create a new client", className, "error");
            throw new EventDeliveryException("Client was closed due to error. Please create a new client");
        }
    }

    public int getBatchSize() {
        return this.batchSize;
    }

    public void sendLog(String logtype, ByteBuffer logByte) throws EventDeliveryException {
        if (!LogValidator.isLegalLogType(logtype)) {
            throw new EventDeliveryException("logtype params [" + logtype + "] format is invalid");
        } else if (logByte == null) {
            throw new EventDeliveryException("one or more params is null");
        } else {
            this.sender.incrTotal(1L);
            DealerType dealerType = this.isFiltered(logtype);
            if (DealerType.abandon == dealerType) {
                this.logfile.writeLog("send logtype " + logtype + " ignored", className, "warn");
            } else {
                Date begin = new Date();

                try {
                    this.checkActive();
                    ThriftFlumeEvent tfe = new ThriftFlumeEvent();
                    tfe.setHeaders(EventHelper.getHead(true, (String)null, logtype, this.config, this.getSendQueueCurrentSize()));
                    this.doFilterDealer(dealerType, logtype, tfe.getHeaders());
                    tfe.setBody(logByte);
                    if (this.eventExceedMaxSize(tfe)) {
                        this.logfile.writeLog("append logtype " + logtype + " log fail, msg size too long \n" + new String(tfe.getBody(), "utf-8"), className, "warn");
                        return;
                    }

                    this.sender.incrActualTotal(1L);
                    this.sender.sendEvent(tfe);
                } catch (Exception var6) {
                    this.logfile.writeExecption(var6);
                    throw new EventDeliveryException(var6);
                }

                Date end = new Date();
                this.logfile.writeLog("send ByteBuffer success response time is :[" + (end.getTime() - begin.getTime()) + "ms]", className, this.dealWithUsetime(end.getTime() - begin.getTime()));
            }
        }
    }

    public void sendLog(String logString) throws EventDeliveryException {
        if (logString == null) {
            throw new EventDeliveryException("logString is null");
        } else {
            this.sender.incrTotal(1L);
            Date begin = new Date();

            try {
                this.checkActive();
                ThriftFlumeEvent tfe = new ThriftFlumeEvent();
                tfe.setHeaders(EventHelper.getHead(false, "", "", this.config, this.getSendQueueCurrentSize()));
                tfe.setBody(ByteBuffer.wrap(logString.getBytes("UTF-8")));
                if (this.eventExceedMaxSize(tfe)) {
                    this.logfile.writeLog("append  log fail, msg size too long \n" + new String(tfe.getBody(), "utf-8"), className, "warn");
                    return;
                }

                this.sender.incrActualTotal(1L);
                this.sender.sendEvent(tfe);
            } catch (Exception var4) {
                this.logfile.writeExecption(var4);
                throw new EventDeliveryException(var4);
            }

            Date end = new Date();
            this.logfile.writeLog("send String success response time is :[" + (end.getTime() - begin.getTime()) + "ms]", className, this.dealWithUsetime(end.getTime() - begin.getTime()));
        }
    }

    public void sendLog(String logtype, Map<String, String> logmap, ByteBuffer logbyte) throws EventDeliveryException {
        if (!LogValidator.isLegalLogType(logtype)) {
            throw new EventDeliveryException("logtype params [" + logtype + "] format is invalid");
        } else if (logmap != null && !logmap.isEmpty()) {
            this.sender.incrTotal(1L);
            DealerType dealerType = this.isFiltered(logtype, logmap);
            if (DealerType.abandon == dealerType) {
                this.logfile.writeLog("send logtype " + logtype + " ignored", className, "warn");
            } else {
                Date begin = new Date();
                StringBuilder logString = new StringBuilder();

                try {
                    this.checkActive();
                    ThriftFlumeEvent tfe = new ThriftFlumeEvent();
                    logString.append(EventHelper.mapToString(logmap, false));

                    this.logfile.writeLog(logString.toString()+"~"+this.configFile+"~"+this.config.getMasterContainKeys()+"~"+this.mustContainKeys, className, "info");

                    if(logbyte != null){
                        Map<String, String> headsMap = EventHelper.getHead(true, (String)null, logtype, this.config, this.getSendQueueCurrentSize());
                        this.doFilterDealer(dealerType, logtype, headsMap);
                        ByteBuffer strbuffer = ByteBuffer.wrap((new String(logString)).getBytes("UTF-8"));
                        headsMap.put("stringBufferLength", "" + strbuffer.array().length);
                        tfe.setHeaders(headsMap);
                        byte[] bytes = new byte[strbuffer.array().length + logbyte.array().length + 8];
                        int strlen = strbuffer.array().length;

                        String stringBufferLength;
                        for(stringBufferLength = Integer.valueOf(strlen).toString(); stringBufferLength.length() != 8; stringBufferLength = "0" + stringBufferLength) {
                            ;
                        }

                        byte[] bytesLength = stringBufferLength.getBytes();

                        int bytelen;
                        for(bytelen = 0; bytelen < bytesLength.length; ++bytelen) {
                            bytes[bytelen] = bytesLength[bytelen];
                        }

                        for(bytelen = 0; bytelen < strlen; ++bytelen) {
                            bytes[8 + bytelen] = strbuffer.array()[bytelen];
                        }

                        bytelen = logbyte.array().length;

                        for(int i = 0; i < bytelen; ++i) {
                            bytes[8 + i + strbuffer.array().length] = logbyte.array()[i];
                        }

                        tfe.setBody(ByteBuffer.wrap(bytes));

                    }else{
                        //logString.append(new String("logtype~" + logtype + '\u001f'));
                        tfe.setHeaders(EventHelper.getHead(false, null, logtype, this.config, this.getSendQueueCurrentSize()));
                        this.doFilterDealer(dealerType, logtype, tfe.getHeaders());
                        tfe.setBody(ByteBuffer.wrap((new String(logString)).getBytes("UTF-8")));

                    }

                    if (this.eventExceedMaxSize(tfe)) {
                        this.logfile.writeLog("append logtype " + logtype + " log fail, msg size too long \n" + new String(tfe.getBody(), "utf-8"), className, "warn");
                        return;
                    }

                    this.sender.incrActualTotal(1L);
                    this.sender.sendEvent(tfe);
                } catch (Exception var16) {
                    this.logfile.writeExecption(var16);
                    throw new EventDeliveryException(var16);
                }

                Date end = new Date();
                long usetime = end.getTime() - begin.getTime();
                String sendLogLevel = this.dealWithUsetime(usetime);
                List<HostInfo> hostInfos = this.config.getHostInfo();
                HostInfo host = hostInfos.get(RandomUtils.randomInt(0, hostInfos.size()));
                this.logfile.writeLog(host.toString() + " " + "sendLog success response time is :[" + usetime + "ms]", className, sendLogLevel);
            }
        } else {
            throw new EventDeliveryException("logtype or logmap or logbyte is null");
        }
    }

    public void sendLog(String logtype, String logString) throws EventDeliveryException {
        if (!LogValidator.isLegalLogType(logtype)) {
            throw new EventDeliveryException("logtype params [" + logtype + "] format is invalid");
        } else if (logString == null) {
            throw new EventDeliveryException("one or more params is null");
        } else {
            this.sender.incrTotal(1L);
            DealerType dealerType = this.isFiltered(logtype);
            if (DealerType.abandon == dealerType) {
                this.logfile.writeLog("send logtype " + logtype + " ignored", className, "warn");
            } else {
                Date begin = new Date();

                try {
                    this.checkActive();
                    ThriftFlumeEvent tfe = new ThriftFlumeEvent();
                    tfe.setHeaders(EventHelper.getHead(false, (String)null, logtype, this.config, this.getSendQueueCurrentSize()));
                    this.doFilterDealer(dealerType, logtype, tfe.getHeaders());
                    tfe.setBody(ByteBuffer.wrap(logString.getBytes("UTF-8")));
                    if (this.eventExceedMaxSize(tfe)) {
                        this.logfile.writeLog("append logtype " + logtype + " log fail, msg size too long \n" + new String(tfe.getBody(), "utf-8"), className, "warn");
                        return;
                    }

                    this.sender.incrActualTotal(1L);
                    this.sender.sendEvent(tfe);
                } catch (Exception var6) {
                    this.logfile.writeExecption(var6);
                    throw new EventDeliveryException(var6);
                }

                Date end = new Date();
                this.logfile.writeLog("send String success response time is :[" + (end.getTime() - begin.getTime()) + "ms]", className, this.dealWithUsetime(end.getTime() - begin.getTime()));
            }
        }
    }

    public void sendLog(String appid, String logtype, Map<String, String> logmap) throws EventDeliveryException {
        if (!LogValidator.isLegalLogType(logtype)) {
            throw new EventDeliveryException("logtype params [" + logtype + "] format is invalid");
        } else if (logmap != null && !StringUtils.isEmpty(appid)) {
            this.sender.incrTotal(1L);
            DealerType dealerType = this.isFiltered(logtype, logmap);
            if (DealerType.abandon == dealerType) {
                this.logfile.writeLog("send logtype " + logtype + " ignored", className, "warn");
            } else {
                Date begin = new Date();
                StringBuilder logString = new StringBuilder();

                try {
                    this.checkActive();
                    this.suppleAppId(appid, logmap);
                    logString.append(new String("logtype~" + logtype + '\u001f'));
                    logString.append(EventHelper.mapToString(logmap, true));
                    if (!this.isContainMuster(logmap)) {
                        throw new EventDeliveryException("log doesn't contain must contain keys.");
                    }

                    ThriftFlumeEvent tfe = new ThriftFlumeEvent();
                    tfe.setHeaders(EventHelper.getHead(false, appid, logtype, this.config, this.getSendQueueCurrentSize()));
                    this.doFilterDealer(dealerType, logtype, tfe.getHeaders());
                    tfe.setBody(ByteBuffer.wrap((new String(logString)).getBytes("UTF-8")));
                    if (this.eventExceedMaxSize(tfe)) {
                        this.logfile.writeLog("append logtype " + logtype + " log fail, msg size too long \n" + new String(tfe.getBody(), "utf-8"), className, "warn");
                        return;
                    }

                    this.sender.incrActualTotal(1L);
                    this.sender.sendEvent(tfe);
                } catch (Exception var8) {
                    this.logfile.writeExecption(var8);
                    throw new EventDeliveryException(var8);
                }

                Date end = new Date();
                this.logfile.writeLog("SendLog success response time is :[" + (end.getTime() - begin.getTime()) + "ms]", className, this.dealWithUsetime(end.getTime() - begin.getTime()));
            }
        } else {
            throw new EventDeliveryException("one or more params is null");
        }
    }

    public void sendLog(String logtype, Map<String, String> logmap) throws EventDeliveryException {
        if (!LogValidator.isLegalLogType(logtype)) {
            throw new EventDeliveryException("logtype params [" + logtype + "] format is invalid");
        } else if (logmap == null) {
            throw new EventDeliveryException("one or more params is null");
        } else {
            this.sender.incrTotal(1L);
            DealerType dealerType = this.isFiltered(logtype, logmap);
            if (DealerType.abandon == dealerType) {
                this.logfile.writeLog("send logtype " + logtype + " ignored", className, "warn");
            } else {
                Date begin = new Date();
                StringBuilder logString = new StringBuilder();

                try {
                    this.checkActive();
                    logString.append(new String("logtype~" + logtype + '\u001f'));
                    logString.append(EventHelper.mapToString(logmap, true));
                    if (!this.isContainMuster(logmap)) {
                        throw new EventDeliveryException("log doesn't contain must contain keys.");
                    }

                    ThriftFlumeEvent tfe = new ThriftFlumeEvent();
                    tfe.setHeaders(EventHelper.getHead(false, (String)null, logtype, this.config, this.getSendQueueCurrentSize()));
                    this.doFilterDealer(dealerType, logtype, tfe.getHeaders());
                    tfe.setBody(ByteBuffer.wrap((new String(logString)).getBytes("UTF-8")));
                    if (this.eventExceedMaxSize(tfe)) {
                        this.logfile.writeLog("append logtype " + logtype + " log fail, msg size too long \n" + new String(tfe.getBody(), "utf-8"), className, "warn");
                        return;
                    }

                    this.sender.incrActualTotal(1L);
                    this.sender.sendEvent(tfe);
                } catch (Exception var7) {
                    this.logfile.writeExecption(var7);
                    throw new EventDeliveryException(var7);
                }

                Date end = new Date();
                this.logfile.writeLog("SendLog success response time is :[" + (end.getTime() - begin.getTime()) + "ms]", className, this.dealWithUsetime(end.getTime() - begin.getTime()));
            }
        }
    }

    public void sendLogBatch(List<String> logStrings) throws EventDeliveryException {
        if (logStrings == null) {
            throw new EventDeliveryException("one or more params is null");
        } else {
            this.sender.incrTotal((long)logStrings.size());
            Date begin = new Date();

            try {
                this.checkActive();
                List<ThriftFlumeEvent> tfes = new ArrayList();
                int i = 0;

                while(true) {
                    if (i >= logStrings.size()) {
                        this.sender.incrActualTotal((long)logStrings.size());
                        this.sender.sendEvent(tfes);
                        break;
                    }

                    ThriftFlumeEvent tfe = new ThriftFlumeEvent();
                    tfe.setHeaders(EventHelper.getHead(false, "", "", this.config, this.getSendQueueCurrentSize()));
                    tfe.setBody(ByteBuffer.wrap(((String)logStrings.get(i)).getBytes("UTF-8")));
                    if (this.eventExceedMaxSize(tfe)) {
                        this.logfile.writeLog("append log fail, msg size too long \n" + new String(tfe.getBody(), "utf-8"), className, "warn");
                    } else {
                        tfes.add(tfe);
                    }

                    ++i;
                }
            } catch (Exception var6) {
                this.logfile.writeExecption(var6);
                throw new EventDeliveryException(var6);
            }

            Date end = new Date();
            this.logfile.writeLog("send Strings success response time is :[" + (end.getTime() - begin.getTime()) + "ms]", className, this.dealWithUsetime(end.getTime() - begin.getTime()));
        }
    }

    public void sendLogBatch(String appid, String logtype, List<Map<String, String>> logMaps) throws EventDeliveryException {
        if (!LogValidator.isLegalLogType(logtype)) {
            throw new EventDeliveryException("logtype params [" + logtype + "] format is invalid");
        } else if (logMaps != null && !StringUtils.isEmpty(appid)) {
            Date begin = new Date();
            this.sender.incrTotal((long)logMaps.size());

            try {
                this.checkActive();
                List<ThriftFlumeEvent> tfes = new ArrayList();

                for(int i = 0; i < logMaps.size(); ++i) {
                    this.suppleAppId(appid, (Map)logMaps.get(i));
                    DealerType dealerType = this.isFiltered(logtype, (Map)logMaps.get(i));
                    if (DealerType.abandon == dealerType) {
                        this.logfile.writeLog("send logtype " + logtype + " ignored", className, "warn");
                    } else {
                        if (!this.isContainMuster((Map)logMaps.get(i))) {
                            throw new EventDeliveryException("log doesn't contain must contain keys.");
                        }

                        StringBuilder logString = new StringBuilder();
                        logString.append("logtype~" + logtype + '\u001f');
                        logString.append(EventHelper.mapToString((Map)logMaps.get(i), true));
                        ThriftFlumeEvent tfe = new ThriftFlumeEvent();
                        tfe.setHeaders(EventHelper.getHead(false, appid, logtype, this.config, this.getSendQueueCurrentSize()));
                        this.doFilterDealer(dealerType, logtype, tfe.getHeaders());
                        tfe.setBody(ByteBuffer.wrap((new String(logString)).getBytes("UTF-8")));
                        if (this.eventExceedMaxSize(tfe)) {
                            this.logfile.writeLog("append logtype " + logtype + " log fail, msg size too long \n" + new String(tfe.getBody(), "utf-8"), className, "warn");
                        } else {
                            tfes.add(tfe);
                        }
                    }
                }

                this.sender.incrActualTotal((long)tfes.size());
                this.sender.sendEvent(tfes);
            } catch (Exception var10) {
                this.logfile.writeExecption(var10);
                throw new EventDeliveryException(var10);
            }

            Date end = new Date();
            this.logfile.writeLog("SendLog success response time is :[" + (end.getTime() - begin.getTime()) + "ms]", className, this.dealWithUsetime(end.getTime() - begin.getTime()));
        } else {
            throw new EventDeliveryException("one or more params is null");
        }
    }

    public void sendLogBatch(String logtype, List<Map<String, String>> logMaps) throws EventDeliveryException {
        if (!LogValidator.isLegalLogType(logtype)) {
            throw new EventDeliveryException("logtype params [" + logtype + "] format is invalid");
        } else if (logMaps == null) {
            throw new EventDeliveryException("one or more params is null");
        } else {
            Date begin = new Date();
            this.sender.incrTotal((long)logMaps.size());

            try {
                this.checkActive();
                List<ThriftFlumeEvent> tfes = new ArrayList();

                for(int i = 0; i < logMaps.size(); ++i) {
                    DealerType dealerType = this.isFiltered(logtype, (Map)logMaps.get(i));
                    if (DealerType.abandon == dealerType) {
                        this.logfile.writeLog("send logtype " + logtype + " ignored", className, "warn");
                    } else {
                        if (!this.isContainMuster((Map)logMaps.get(i))) {
                            throw new EventDeliveryException("log doesn't contain must contain keys.");
                        }

                        StringBuilder logString = new StringBuilder();
                        logString.append("logtype~" + logtype + '\u001f');
                        logString.append(EventHelper.mapToString((Map)logMaps.get(i), true));
                        ThriftFlumeEvent tfe = new ThriftFlumeEvent();
                        tfe.setHeaders(EventHelper.getHead(false, (String)null, logtype, this.config, this.getSendQueueCurrentSize()));
                        this.doFilterDealer(dealerType, logtype, tfe.getHeaders());
                        tfe.setBody(ByteBuffer.wrap((new String(logString)).getBytes("UTF-8")));
                        if (this.eventExceedMaxSize(tfe)) {
                            this.logfile.writeLog("append logtype " + logtype + " log fail, msg size too long \n" + new String(tfe.getBody(), "utf-8"), className, "warn");
                        } else {
                            tfes.add(tfe);
                        }
                    }
                }

                this.sender.incrActualTotal((long)tfes.size());
                this.sender.sendEvent(tfes);
            } catch (Exception var9) {
                this.logfile.writeExecption(var9);
                throw new EventDeliveryException(var9);
            }

            Date end = new Date();
            this.logfile.writeLog("SendLog success response time is :[" + (end.getTime() - begin.getTime()) + "ms]", className, this.dealWithUsetime(end.getTime() - begin.getTime()));
        }
    }

    private void doFilterDealer(DealerType dealerType, String logType, Map<String, String> header) {
        switch(dealerType) {
            case addheader:
                this.router.doLogTypeAddHeader(logType, header);
            default:
        }
    }

    public boolean isActive() {
        return this.connState == TraceLogClient.State.READY;
    }

    public void close() {
        try {
            this.stateLock.lock();
            this.connState = TraceLogClient.State.DEAD;
            if (this.sender != null) {
                this.sender.close();
            }
        } finally {
            this.stateLock.unlock();
        }

    }

    private String dealWithUsetime(long usetime) {
        String sendLogLevel = "debug";
        if (usetime > 500L && usetime < 1000L) {
            sendLogLevel = "info";
        }

        if (usetime >= 1000L && usetime < 2000L) {
            sendLogLevel = "warn";
        }

        if (usetime >= 2000L) {
            sendLogLevel = "error";
        }

        return sendLogLevel;
    }

    private boolean isContainMuster(Map<String, String> logMap) {
        boolean ret = true;

        for(int i = 0; i < this.mustContainKeys.length && ret; ++i) {
            ret = ret && logMap.containsKey(this.mustContainKeys[i]);
        }

        return ret;
    }

    private void initRouter(String filterFile) {
        try {
            XStream xs = new XStream();
            xs.processAnnotations(Router.class);
            InputStreamReader fis = new InputStreamReader(new FileInputStream(filterFile), "utf-8");
            Router routerFile = (Router)xs.fromXML(fis);
            RouterConfig routerConfig = new RouterConfig(routerFile);
            this.router = new RouterUtils(routerConfig.getRouterConfig(), this.configFile, this.config);
            this.logfile.writeLog("load router file " + filterFile + " success, filter info: " + routerFile.toString(), className, "info");
        } catch (Exception var6) {
            this.logfile.writeExecption(var6);
        }

    }

    private DealerType isFiltered(String logtype, Map<String, String> logmap) {
        try {
            if (this.router != null) {
                DealerType type = this.router.filterLog(logmap, logtype);
                return type;
            } else {
                return DealerType.donothing;
            }
        } catch (Exception var4) {
            this.logfile.writeExecption(var4);
            return DealerType.donothing;
        }
    }

    private DealerType isFiltered(String logtype) {
        try {
            return this.router != null ? this.router.filterLog(logtype) : DealerType.donothing;
        } catch (Exception var3) {
            this.logfile.writeExecption(var3);
            return DealerType.donothing;
        }
    }

    private void suppleAppId(String appid, Map<String, String> eventBody) {
        if (!eventBody.containsKey("appid") || StringUtils.isEmpty((String)eventBody.get("appid"))) {
            eventBody.put("appid", appid);
        }

    }

    private boolean eventExceedMaxSize(ThriftFlumeEvent event) {
        return (long)event.getBody().length >= this.config.getMsgMaxSize();
    }

    @Override
    public long getTotal() {
        return this.sender.getTotal();
    }
    @Override
    public long getActualTotal() {
        return this.sender.getAcutalTotal();
    }
    @Override
    public long getCountOfWToFile() {
        return this.sender.getCountOfWToFile();
    }
    @Override
    public long getCountOfDirectSend() {
        return this.sender.getCountOfDirectSend();
    }
    @Override
    public long getUsedQueueSize() {
        return this.sender.queueUsedSize();
    }
    @Override
    public long getCountOfSendFromFile() {
        return this.sender.getCountOfRFromFile();
    }

    private static enum State {
        INIT,
        READY,
        DEAD;

        private State() {
        }
    }
}

